package com.hqd.jjvm.jnative.lang;

import com.hqd.jjvm.jnative.JNativeRegistry;
import com.hqd.jjvm.rtda.JThread;
import com.hqd.jjvm.rtda.heap.JClass;
import com.hqd.jjvm.rtda.heap.JField;
import com.hqd.jjvm.rtda.heap.classloader.JClassLoader;
import com.hqd.jjvm.rtda.obj.JObject;

import java.io.IOException;

public class JThreadNativeRegistry extends JNativeRegistry {
    private static final JThreadNativeRegistry instance = new JThreadNativeRegistry();
    protected static final String CLASS_PATH = "java/lang/Thread";

    static {
        registry(CLASS_PATH, "registerNatives", "()V", JNativeRegistry::registerNatives);
        registry(CLASS_PATH, "currentThread", "()Ljava/lang/Thread;", JThreadNativeRegistry::currentThread);
        registry(CLASS_PATH, "setPriority0", "(I)V", JThreadNativeRegistry::setPriority0);
        registry(CLASS_PATH, "isAlive", "()Z", JThreadNativeRegistry::isAlive);
        registry(CLASS_PATH, "start0", "()V", JThreadNativeRegistry::start0);

    }

    protected static void start0(JThread jThread) {
    }

    protected static void isAlive(JThread jThread) {
        jThread.getJvmStack().pushOperandStackIntVal(0);
    }

    protected static void setPriority0(JThread jThread) {
    }

    protected static void currentThread(JThread jThread) {
        JClassLoader loader = jThread.getJvmStack().getTop().getJClass().getLoader();
        try {
            JClass threadJClass = loader.loadJClass("java/lang/Thread");
            JObject thread = threadJClass.newJObject();
            JClass groupJClass = loader.loadJClass("java/lang/ThreadGroup");
            JObject groupObj = groupJClass.newJObject();
            JField[] jFields = threadJClass.getJFields();
            JField jField = null;
            for (JField jf : jFields) {
                if (jf.getName().equals("group") && jf.getDescriptor().equals("Ljava/lang/ThreadGroup;")) {
                    jField = jf;
                    break;
                }
            }
            thread.getFields()[jField.getSlotId()].setVal(groupObj);
            for (JField jf : jFields) {
                if (jf.getName().equals("priority") && jf.getDescriptor().equals("I")) {
                    jField = jf;
                    break;
                }
            }
            thread.getFields()[jField.getSlotId()].setVal(1);
            jThread.getJvmStack().pushOperandStackRefVal(thread);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static JThreadNativeRegistry getInstance() {
        return instance;
    }
}
